
// 定义屏幕宽度和高度的宏
#define SCREEN_WIDTH 240
#define SCREEN_HEIGHT 320

// 定义背光引脚
#define TFT_bl 25

// 定义背光亮度值
int bl = 50;
// 新增计数器，用于控制每隔1秒打印一次
int printCounter = 0;
// 定义TFT_eSPI库的对象并初始化
TFT_eSPI tft = TFT_eSPI();

class TextDisplayer
{
private:
    int lastTextX;
    int lastTextY;
    int lastTextWidth;
    int lastTextHeight;
    String lastTextdata;
    uint32_t lastTextcolor;

public:
    TextDisplayer() : lastTextX(0), lastTextY(0), lastTextWidth(0), lastTextHeight(0), lastTextdata(""), lastTextcolor(0) {}

    void display(int x, int y, String data, int size, int font, uint32_t color)
    {
        if (color == TFT_RED || color != lastTextcolor || lastTextdata != data)
        {
            // 获取当前文字尺寸
            tft.setTextSize(size);
            tft.setTextFont(font);
            tft.setTextColor(color, TFT_BLACK); // 字体颜色/背景色
            int textWidth = tft.textWidth(data);
            int textHeight = tft.fontHeight();
            // 计算当前文字位置
            int textX = x - textWidth / 2;
            int textY = y - textHeight / 2;

            // 用矩形清空上一次文字显示区域
            if (lastTextX != 0 && lastTextY != 0)
            {
                tft.fillRect(lastTextX, lastTextY, lastTextWidth, lastTextHeight, TFT_BLACK);
            }
            // 显示新文字
            tft.drawString(data.c_str(), textX, textY);

            // 更新上一次绘制字符区域的相关信息
            lastTextcolor = color;
            lastTextdata = data;
            lastTextX = textX;
            lastTextY = textY;
            lastTextWidth = textWidth;
            lastTextHeight = textHeight;
            tft.setTextColor(TFT_WHITE, TFT_BLACK); // 字体颜色/背景色
        }
    }
    void ResetlastTextdata()
    {
        lastTextcolor = 0;
        lastTextdata = "";
        lastTextX = 0;
        lastTextY = 0;
        lastTextWidth = 0;
        lastTextHeight = 0;
    }
};
// 定义TextDisplayer类的对象
TextDisplayer displayer0, displayer1, displayer2, displayer3, displayer4, displayer5, displayer6, displayer7, displayer8;

// 新增全局变量用于标记电池组画面是否需要重新绘制固定元素
bool shouldRedrawBatteryPackStaticElements;
// 新增全局变量用于标记并网画面是否需要重新绘制固定元素
bool shouldRedrawStaticElements;
bool shouldRedrawGridAndUsageElements;

// 新增全局变量用于记录当前显示的画面（0: 电池组画面, 1: 并网画面）
int currentScreen = 0;

// 状态栏打印函数
void tftPrintf(String data, uint32_t color)
{
    displayer0.display(SCREEN_WIDTH / 2, 12, data, 2, 1, color);
    analogWrite(TFT_bl, bl);
}

// 定义用于打印报错信息和时间的函数
void printErrorAndTime()
{
    static bool showError = false; // 标志位，true表示显示错误信息，false表示显示时间
    static int lastSeconds = 0;
    struct tm time_info;
    time_t now;
    time(&now);
    localtime_r(&now, &time_info);
    int hours = time_info.tm_hour;
    int minutes = time_info.tm_min;
    int seconds = time_info.tm_sec;

    if (seconds != lastSeconds) // 这里只是为了保留类似逻辑结构，实际可根据需求调整
    {
        lastSeconds = seconds;
        if (showError)
        {
            printCounter++;
            if (printCounter == 1)
            {
                if (WiFi.status() != WL_CONNECTED)
                {
                    tftPrintf("WiFi", TFT_RED);
                }
                else
                {
                    printCounter++;
                }
            }
            if (printCounter == 2)
            {
                if (!TCPclient.connected())
                {
                    tftPrintf("Bfy", TFT_RED);
                }
                else
                {
                    printCounter++;
                }
            }
            if (printCounter == 3)
            {
                if (!UdpkStatus)
                {
                    tftPrintf("Udp", TFT_RED);
                }
                else
                {
                    printCounter++;
                }
            }
            if (printCounter == 4)
            {
                if (!aizkStatus)
                {
                    tftPrintf("Azk", TFT_RED);
                }
                else
                {
                    printCounter++;
                }
            }
            if (printCounter == 5)
            {
                if (!acsStatus)
                {
                    tftPrintf("Acs", TFT_RED);
                }
                else
                {
                    printCounter++;
                }
            }
            if (printCounter == 6)
            {
                showError = !showError;
                printCounter = 0; // 全部打印完后，重置计数器
            }
        }
        if (!showError)
        {
            char time_str[9];
            sprintf(time_str, "%02d:%02d:%02d", hours, minutes, seconds);
            tftPrintf(time_str, TFT_WHITE);
            showError = !showError;
        }
    }
}

// 显示电池组画面的函数
void displayBatteryPackScreen()
{
    char buffer[6];
    if (shouldRedrawBatteryPackStaticElements)
    {
        tft.fillScreen(TFT_BLACK);
        tft.drawRoundRect(0, 30, SCREEN_WIDTH, SCREEN_HEIGHT - 30, 30, TFT_WHITE); // 空心圆角矩形  //设定圆角半径,这里设为30,可按需调整
        tft.setTextSize(1);
        tft.drawCentreString("Parameters of Battery", SCREEN_WIDTH / 2, 50, 2);
        tft.drawCentreString("Min", SCREEN_WIDTH / 6, 255, 2);
        tft.drawCentreString("Diff", SCREEN_WIDTH / 2, 240, 2);
        tft.drawCentreString("Max", SCREEN_WIDTH - SCREEN_WIDTH / 6, 255, 2);
        tft.drawFastHLine(0, 158, SCREEN_WIDTH, TFT_WHITE);
        tft.drawFastHLine(0, 236, SCREEN_WIDTH, TFT_WHITE);
        tft.drawFastHLine(SCREEN_WIDTH / 3, 283, SCREEN_WIDTH / 3, TFT_WHITE);
        tft.drawFastVLine(SCREEN_WIDTH / 2, 158, 78, TFT_WHITE);
        shouldRedrawBatteryPackStaticElements = false;
    }
    sprintf(buffer, "%.3f", batteryVoltage);
    displayer1.display(SCREEN_WIDTH / 2, 120, buffer, 1, 6, TFT_WHITE);
    tft.setTextSize(1);
    tft.drawCentreString("Vol", SCREEN_WIDTH / 2, 135, 2);

    sprintf(buffer, "%.1f", batteryCurrent);
    displayer2.display(SCREEN_WIDTH / 4, 200, buffer, 1, 6, TFT_WHITE);
    tft.setTextSize(1);
    tft.drawCentreString("Current", SCREEN_WIDTH / 4, 215, 2);

    sprintf(buffer, "%.0f", batteryPower);
    displayer3.display(SCREEN_WIDTH * 3 / 4, 200, buffer, 1, 6, TFT_WHITE);
    tft.setTextSize(1);
    tft.drawCentreString("Power", SCREEN_WIDTH * 3 / 4, 215, 2);

    // displayer4.display(SCREEN_WIDTH / 6, 285, String(minCellVoltage), 1, 4, TFT_WHITE);
    // displayer5.display(SCREEN_WIDTH / 2, 270, String(int(voltageDifference)), 1, 4, TFT_WHITE);
    // displayer6.display(SCREEN_WIDTH * 5 / 6, 285, String(maxCellVoltage), 1, 4, TFT_WHITE);
    // displayer7.display(SCREEN_WIDTH / 2, 302, String(int(batteryPackTemperature)), 1, 4, TFT_WHITE);
}

// 显示并网和用电侧数据画面的函数
void displayGridAndUsageScreen()
{
    if (shouldRedrawGridAndUsageElements)
    {
        tft.fillScreen(TFT_BLACK);
        // 绘制固定元素，如标题等
        tft.drawRoundRect(0, 30, SCREEN_WIDTH, SCREEN_HEIGHT - 30, 30, TFT_WHITE); // 空心圆角矩形  //设定圆角半径,这里设为30,可按需调整
        tft.setTextSize(1);
        tft.drawCentreString("Grid & Usage Info", SCREEN_WIDTH / 2, 50, 2);
        shouldRedrawGridAndUsageElements = false;
    }

    // 显示用电侧电流
    displayer1.display(SCREEN_WIDTH / 4, 100, String(usageCurrent), 1, 4, TFT_WHITE);
    tft.setTextSize(1);
    tft.drawCentreString("Usage Cur", SCREEN_WIDTH / 4, 115, 2);

    // 显示用电侧功率
    displayer2.display(SCREEN_WIDTH / 4, 150, String(usagePower), 1, 4, TFT_WHITE);
    tft.setTextSize(1);
    tft.drawCentreString("Usage Pow", SCREEN_WIDTH / 4, 165, 2);

    // 显示用电侧电能
    displayer3.display(SCREEN_WIDTH / 4, 200, String(usageEnergy), 1, 4, TFT_WHITE);
    tft.setTextSize(1);
    tft.drawCentreString("Usage Ene", SCREEN_WIDTH / 4, 215, 2);

    // 显示用电侧功率因素
    displayer4.display(SCREEN_WIDTH / 4, 250, String(usagePowerFactor), 1, 4, TFT_WHITE);
    tft.setTextSize(1);
    tft.drawCentreString("Usage PF", SCREEN_WIDTH / 4, 265, 2);

    // 显示并网侧电流
    displayer5.display(3 * SCREEN_WIDTH / 4, 100, String(gridCurrent), 1, 4, TFT_WHITE);
    tft.setTextSize(1);
    tft.drawCentreString("Grid Cur", 3 * SCREEN_WIDTH / 4, 115, 2);

    // 显示并网侧功率
    displayer6.display(3 * SCREEN_WIDTH / 4, 150, String(gridPower), 1, 4, TFT_WHITE);
    tft.setTextSize(1);
    tft.drawCentreString("Grid Pow", 3 * SCREEN_WIDTH / 4, 165, 2);

    // 显示并网侧电能
    displayer7.display(3 * SCREEN_WIDTH / 4, 200, String(gridEnergy), 1, 4, TFT_WHITE);
    tft.setTextSize(1);
    tft.drawCentreString("Grid Ene", 3 * SCREEN_WIDTH / 4, 215, 2);

    // 显示并网侧功率因素
    displayer8.display(3 * SCREEN_WIDTH / 4, 250, String(gridPowerFactor), 1, 4, TFT_WHITE);
    tft.setTextSize(1);
    tft.drawCentreString("Grid PF", 3 * SCREEN_WIDTH / 4, 265, 2);
}
// 显示蓄电池、光伏板等相关数据画面的函数
void displayBatteryAndPVScreen()
{
    if (shouldRedrawStaticElements)
    {
        tft.fillScreen(TFT_BLACK);
        // 绘制固定元素，如标题等
        tft.drawRoundRect(0, 30, SCREEN_WIDTH, SCREEN_HEIGHT - 30, 30, TFT_WHITE); // 空心圆角矩形  //设定圆角半径,这里设为30,可按需调整
        tft.setTextSize(1);
        tft.drawCentreString("Battery & Mppt", SCREEN_WIDTH / 2, 50, 2);
        shouldRedrawStaticElements = false;
    }

    // 显示蓄电池电压
    displayer1.display(SCREEN_WIDTH / 4, 110, String(batteryVoltage), 1, 4, TFT_WHITE);
    tft.setTextSize(1);
    tft.drawCentreString("Batt Vol", SCREEN_WIDTH / 4, 120, 2);

    // 显示蓄电池电流
    displayer2.display(3 * SCREEN_WIDTH / 4, 110, String(batteryCurrent), 1, 4, TFT_WHITE);
    tft.setTextSize(1);
    tft.drawCentreString("Batt Cur", 3 * SCREEN_WIDTH / 4, 120, 2);

    // 显示光伏板电压
    displayer3.display(SCREEN_WIDTH / 4, 166, String(pvVoltage), 1, 4, TFT_WHITE);
    tft.setTextSize(1);
    tft.drawCentreString("PV Vol", SCREEN_WIDTH / 4, 176, 2);

    // 显示光伏板电流
    displayer4.display(3 * SCREEN_WIDTH / 4, 166, String(pvCurrent), 1, 4, TFT_WHITE);
    tft.setTextSize(1);
    tft.drawCentreString("PV Cur", 3 * SCREEN_WIDTH / 4, 176, 2);

    // 显示光伏板功率
    displayer5.display(SCREEN_WIDTH / 4, 223, String(pvPower), 1, 4, TFT_WHITE);
    tft.setTextSize(1);
    tft.drawCentreString("PV Pow", SCREEN_WIDTH / 4, 233, 2);

    // // 显示控制器温度
    // displayer6.display(3 * SCREEN_WIDTH / 4, 223, String(controllerTemperature), 1, 4, TFT_WHITE);
    // tft.setTextSize(1);
    // tft.drawCentreString("Ctrl Temp", 3 * SCREEN_WIDTH / 4, 233, 2);

    // // 显示累计功率
    // displayer7.display(SCREEN_WIDTH / 2, 280, String(cumulativePower), 1, 4, TFT_WHITE);
    // tft.setTextSize(1);
    // tft.drawCentreString("Cumu Pow", SCREEN_WIDTH / 2, 290, 2);
}

// TFT显示屏初始化函数
void setupTft()
{
    tft.init();
    tft.setRotation(0);
    tft.invertDisplay(false);
    tft.fillScreen(TFT_BLACK);
    tft.setTextColor(TFT_WHITE, TFT_BLACK); // 字体颜色/背景色
    pinMode(TFT_bl, OUTPUT);
    analogWrite(TFT_bl, 0);
    currentScreen = config.currentScreen;
}

// TFT显示屏循环函数
void loopTft()
{
    static long loopTftTick = 0;
    static int previousScreen = -1; // 用于记录上一次显示的画面，初始值设为-1

    if (currentScreen != previousScreen)
    {
        config.currentScreen = currentScreen;
        saveConfig();
        displayer1.ResetlastTextdata();
        displayer2.ResetlastTextdata();
        displayer3.ResetlastTextdata();
        displayer4.ResetlastTextdata();
        displayer5.ResetlastTextdata();
        displayer6.ResetlastTextdata();
        displayer7.ResetlastTextdata();
        displayer8.ResetlastTextdata();
        // 画面切换，设置对应的标记变量为true
        if (currentScreen == 0)
        {
            shouldRedrawBatteryPackStaticElements = true;
            shouldRedrawGridAndUsageElements = false;
            shouldRedrawStaticElements = false;
            displayBatteryPackScreen();
        }
        else if (currentScreen == 1)
        {
            shouldRedrawBatteryPackStaticElements = false;
            shouldRedrawGridAndUsageElements = true;
            shouldRedrawStaticElements = false;
            displayGridAndUsageScreen();
        }
        else if (currentScreen == 2)
        {
            shouldRedrawBatteryPackStaticElements = false;
            shouldRedrawGridAndUsageElements = false;
            shouldRedrawStaticElements = true;
            displayBatteryAndPVScreen();
        }
        previousScreen = currentScreen;
    }
    if (millis() - loopTftTick > 100)
    {
        printErrorAndTime();
        if (currentScreen == 0)
        {
            displayBatteryPackScreen();
        }
        else if (currentScreen == 1)
        {
            displayGridAndUsageScreen();
        }
        else if (currentScreen == 2)
        {
            displayBatteryAndPVScreen();
        }
        loopTftTick = millis();
    }
}
